package com.ruoyi.partybuilding.common;

import cn.hutool.core.date.DateUtil;
import com.easy.query.api4j.select.Queryable;
import com.easy.query.core.api.dynamic.sort.ObjectSort;
import com.easy.query.core.api.pagination.EasyPageResult;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.partybuilding.common.EQuery.CU2Entity;
import com.ruoyi.partybuilding.common.EQuery.CreateByEntity;
import com.ruoyi.partybuilding.common.EQuery.IEQueryEntity;
import lombok.var;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.ResolvableType;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.RequestBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

public abstract class EQueryController<T extends IEQueryEntity> extends BaseController {
    @Resource
    protected EQueryHelper queryHelper;
   protected Queryable<T> equeryable() {
       return queryHelper.query().queryable(tClass);
   }
    final protected Class<T> tClass= (Class<T>) ResolvableType.forClass(getClass()).getSuperType().getGeneric(0).resolve();

    public Page toPageData(EasyPageResult pData) {
        return new PageImpl<>(pData.getData(), Pageable.unpaged(), pData.getTotal());
    }
    public Page toPageData(List list) {
        return new PageImpl<>(list, Pageable.unpaged(), list.size());
    }
    public Page toPageData(List list,Long total) {
        return new PageImpl<>(list, Pageable.unpaged(), total);
    }

    protected R<Page<T>> queryPage(Serializable whereObj, PageDomain pageRequest) {
        if (pageRequest == null) {
            var pData = queryHelper.queryable(tClass)
                    .whereObject(whereObj != null, whereObj)
                    .toList();
            var page = new PageImpl<>(pData, Pageable.unpaged(), pData.size());
            return R.ok(page);
        }

        pageRequest = gainPageDomain(pageRequest);
        var pitem = queryHelper.query().queryable(tClass)
                .whereObject(whereObj != null, whereObj);
        if (pageRequest instanceof ObjectSort)
            pitem.orderByObject((ObjectSort) pageRequest);
        var pData = pitem.orderByDesc(p->p.column(T::getId)).toPageResult(pageRequest.getPageNum(), pageRequest.getPageSize());
        var page = new PageImpl<>(pData.getData(), Pageable.unpaged(), pData.getTotal());
        return R.ok(page);
    }

   protected PageDomain gainPageDomain(PageDomain pageRequest) {
        if (pageRequest == null)
            pageRequest = new PageDomain();
        if (pageRequest.getPageSize() == null)
            pageRequest.setPageSize(10);
        if (pageRequest.getPageNum() == null)
            pageRequest.setPageNum(1);
        return pageRequest;
    }
    public static  <E> TableDataInfoRows<E> toTableDataInfoRows(R<Page<E>> page){
        TableDataInfoRows<E> rspData = new TableDataInfoRows<E>();
        rspData.setCode(page.getCode());
        rspData.setMsg(page.getMsg());
        rspData.setRows(page.getData().getContent());
        rspData.setTotal(page.getData().getTotalElements());
        return rspData;
    }
    public static  <E> TableDataInfoRows<E> toTableDataInfoRows(EasyPageResult<E> page){
        TableDataInfoRows<E> rspData = new TableDataInfoRows<E>();
        rspData.setCode(200);
        rspData.setRows(page.getData());
        rspData.setTotal(page.getTotal());
        return rspData;
    }
    protected TableDataInfoRows<T> list(Serializable whereObj, PageDomain pageRequest) {
        var page = queryPage(whereObj, pageRequest);
        return toTableDataInfoRows(page);
    }
    public R<T> getInfo(Object id)
    {
        return R.ok(equeryable().whereById(id).firstOrNull());
    }
    /**
     * 导出班子记录列表
     */

    //@Log(title = "班子记录", businessType = BusinessType.EXPORT)
    protected void export(Serializable entity, PageDomain pageRequest,String fileName,HttpServletResponse response)
    {
        List<T> list = queryPage(entity,pageRequest).getData().getContent();
        ExcelUtil<T> util = new ExcelUtil<T>(tClass);
        util.exportExcel(response, list, StringUtils.isBlank(fileName)?"数据记录_"+DateUtil.today():fileName);
    }
    protected R<Long> add(@RequestBody T entity) {
        if(entity instanceof CreateByEntity) {
            var cu = ((CreateByEntity<?>) entity);
            if (cu.getCreateTime() == null)
                cu.setCreateTime(new Date());
            if (cu.getCreateBy() == null)
                cu.setCreateBy(getUsername());
        }
        var re = queryHelper.query().insertable(entity).executeRows(true);
        if (re > 0)
            return R.ok(re);
        return R.fail("添加失败");
    }


    protected R<Long> remove(T entity){
        var re= queryHelper.query().deletable(entity)
                .disableLogicDelete().allowDeleteStatement(true)
                .executeRows();
        return R.ok(re);
    }

    protected R<Long> remove(Object[] ids) {

        var count = queryHelper.query().deletable(tClass)
                .disableLogicDelete().allowDeleteStatement(true)
                .whereByIds(Arrays.asList(ids)).executeRows();
        if (ids.length != count)
            logger.warn("批量删除异常", (Object[]) ids);
        return R.ok(count);
    }


     protected R<Long> edit(@RequestBody T entity) {
        if(entity instanceof CU2Entity)
        {
             var cu=((CU2Entity<?>) entity);
             cu.setUpdateTime(new Date());
             cu.setUpdateBy(getUsername());
        }
        var re = queryHelper.query().updatable(entity).executeRows();
        if (re > 0)
            return R.ok(re);
        return R.fail("更新失败");
    }

}
